home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / What's New? / Development Kits / Mac OS / USB DDK 1.4.6f4 / Examples / USBEnetSample / USBEnetDriver.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-08-23  |  43.5 KB  |  1,637 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        USBEnetDriver.c
  3.  
  4.     Contains:    xxx put contents here xxx
  5.  
  6.     Version:    xxx put version here xxx
  7.  
  8.     Copyright:    © 1998-2000 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     File Ownership:
  11.  
  12.         DRI:                xxx put dri here xxx
  13.  
  14.         Other Contact:        xxx put other contact here xxx
  15.  
  16.         Technology:            xxx put technology here xxx
  17.  
  18. */
  19.  
  20. #include <DriverServices.h>
  21.  
  22. #include "USBEnet.h"
  23. #include "USBEnetDriver.h"
  24. #include "ShimEnetHAL.h"
  25.  
  26. enum
  27. {
  28.     kUSBv12    =    0x01200000
  29. };
  30.  
  31. static             EnetPB         gEnetGlobals;
  32. static             USBPB        syncPB, interruptPB, stallPB, delayPB;
  33. static             OSStatus    configerr = noErr;
  34. static volatile Boolean        configured = false;
  35. static             UInt16         errCount;
  36. UInt16                        statusData[8];
  37. UInt8                         Intrretries = 0;
  38. UInt32                        usbVersion = 0;
  39. Boolean                        gUSBVersionNeedsBulkFixPresent;
  40. CFragConnectionID            ConnID;                    // Need to remember this
  41.  
  42. /************************************************************************************/
  43. //
  44. //    CheckUSBVersion
  45. //
  46. //    Determines whether it's USB1.2 (less requires doing safe bulk calls)
  47. //
  48. /************************************************************************************/
  49.  
  50. void    CheckUSBVersion(void)
  51. {
  52. OSStatus    err = 0;
  53.  
  54.     TraceMessage(0, "\pEntering CheckUSBVersion");
  55.     
  56.     err = Gestalt('usbv', (long*)&usbVersion);
  57.         
  58.     if (err == noErr)
  59.         gUSBVersionNeedsBulkFixPresent = (usbVersion < kUSBv12);
  60. }
  61.  
  62. /************************************************************************************/
  63. //
  64. //    USBStatus
  65. //
  66. //    Determines which status call to make.
  67. //
  68. /************************************************************************************/
  69.  
  70. void USBStatus(UInt32 level, USBDeviceRef ref, void *pointer, UInt32 value)
  71. {
  72.     
  73.     if (usbVersion < kUSBv12)
  74.     {
  75.         USBExpertStatus(ref, pointer, value);
  76.     } else {
  77.         USBExpertStatusLevel(level, ref, pointer, value);
  78.     }
  79. }
  80.  
  81. /************************************************************************************/
  82. //
  83. //    AddToRcvList
  84. //
  85. //    Adds the buffer to the receive list.
  86. //
  87. /************************************************************************************/
  88.  
  89. void AddToRcvList(UInt32 bufindx)
  90. {
  91.     
  92.     TraceMessage(0,kDrvName"- Entering AddToRcvList");
  93.     
  94.     Enqueue((QElemPtr)&gGlobals->inBuf[bufindx], &gGlobals->rcvq);
  95.     
  96. }
  97.  
  98. /************************************************************************************/
  99. //
  100. //    RemoveFromRcvList
  101. //
  102. //    Removes the next buffer from the receive list.
  103. //
  104. /************************************************************************************/
  105.  
  106. UInt8* RemoveFromRcvList(UInt32 *indx)
  107. {
  108.     
  109.     OSErr err;
  110.     BuffersPtr next;
  111.  
  112.     TraceMessage(0,kDrvName"- Entering RemoveFromRcvList");
  113.     
  114.     next = (BuffersPtr)gGlobals->rcvq.qHead;        // get first buffer off the list
  115.     if (next == nil) 
  116.         return nil;                                    // empty list
  117.     
  118.     err = Dequeue((QElemPtr)next, &gGlobals->rcvq);
  119.     if (err) 
  120.         return nil;                                    // shouldn't happen
  121.         
  122.     *indx = next->indx;
  123.     return (UInt8*)&next->Buffer;
  124. }
  125.  
  126. /************************************************************************************/
  127. //
  128. //    immediateError
  129. //
  130. //    Determines whether it's an error or just pending.
  131. //
  132. /************************************************************************************/
  133.  
  134. static Boolean immediateError(OSStatus err)
  135. {
  136.     return ((err != kUSBPending) && (err != noErr));
  137. }
  138.  
  139. UInt16    cnter = 0;
  140. UInt8    savOther = 0;
  141. /************************************************************************************/
  142. //
  143. //    ConfigurationHandler
  144. //
  145. //    Configures the USB Device (Ethernet).
  146. //
  147. /************************************************************************************/
  148.  
  149. static void ConfigurationHandler(USBPB *pb)
  150. {
  151.  
  152. //    TraceMessage(0, kDrvName"- Entering ConfigurationHandler");
  153.     StatusMessage(gEnetGlobals.deviceRef, kDrvName"- Entering ConfigurationHandler", pb->usbRefcon);
  154.     
  155.     if(pb->usbStatus != noErr)
  156.     {
  157.         if((gEnetGlobals.onError == kReset) && (gEnetGlobals.retries > 0))
  158.         {
  159.             /* no idea what to do now?? */
  160.             USBExpertFatalError(gEnetGlobals.deviceRef, pb->usbStatus, gEnetGlobals.errorString, pb->usbRefcon);
  161.             
  162.             /* Mark port as errored */
  163.             configured = true;
  164.             configerr = pb->usbStatus;
  165.         }
  166.         else
  167.         {
  168.             StatusMessage(gEnetGlobals.deviceRef, gEnetGlobals.errorString, pb->usbStatus);
  169.             pb->usbRefcon = gEnetGlobals.onError;
  170.  
  171.             USBClearPipeStallByReference(pb->usbReference);
  172.             
  173.             /* we'll delay coming back to here */
  174.             gEnetGlobals.retries--;
  175.  
  176.             pb->usbReqCount = 0;
  177.             USBDelay(pb);
  178.         }        
  179.         return;
  180.     }
  181.  
  182.     gEnetGlobals.onError = kReset;
  183.     
  184.     do{switch(pb->usbRefcon++)
  185.     {
  186.         case kCommConfig:
  187.         
  188.             /* Need to find an interface with a communication class in it */
  189.             pb->usbClassType = kUSBCommClass;
  190.             pb->usbSubclass = 6;                        /* Ethernet Model */
  191.             pb->usbProtocol = 0;
  192.             pb->usb.cntl.WValue = 0;
  193.             pb->usb.cntl.WIndex = 0;
  194.             pb->usbReqCount = 0;
  195.             pb->usbBuffer = nil;
  196.             pb->usbFlags = 0;
  197.             
  198.             if (gEnetGlobals.retries > 0)
  199.             {
  200.                 gEnetGlobals.onError = kCommConfig;
  201.             } else {
  202.                 gEnetGlobals.onError = kReset;
  203.             }            
  204.             noteError(kDrvName"- Finding the Comm Class Interface");            
  205.             if(immediateError(configerr = USBFindNextInterface(pb)))
  206.             {
  207.                 USBExpertFatalError(gEnetGlobals.deviceRef, configerr, gEnetGlobals.errorString, 0);
  208.                 configured = true;
  209.             }
  210.             
  211.         break;
  212.  
  213.         case kSetConfig:
  214.             StatusMessage(gEnetGlobals.deviceRef, kDrvName"- Configuration Number - ", pb->usb.cntl.WValue);
  215.             StatusMessage(gEnetGlobals.deviceRef, kDrvName"- Interface Number - ", pb->usb.cntl.WIndex);
  216.             
  217.             /* Remember the interface number */
  218.             gEnetGlobals.interfacenum = pb->usb.cntl.WIndex;
  219.             
  220.             /* Open the device based on the config found */            
  221.             if (gEnetGlobals.retries > 0)
  222.             {
  223.                 gEnetGlobals.onError = kSetConfig;
  224.             } else {
  225.                 gEnetGlobals.onError = kReset;
  226.             }
  227.             noteError(kDrvName"- Setting the configuration");
  228.             if(immediateError(configerr = USBSetConfiguration(pb)))
  229.             {
  230.                 USBExpertFatalError(gEnetGlobals.deviceRef, configerr, gEnetGlobals.errorString, 0);
  231.                 configured = true;
  232.             }
  233.         
  234.         break;
  235.         
  236.         case kGetCommInterface:
  237.             StatusMessage(gEnetGlobals.deviceRef, kDrvName"- Number of interfaces in Configuration - ", pb->usbOther);
  238.             
  239.             /* Get the interface reference number */
  240.             if (gEnetGlobals.retries > 0)
  241.             {
  242.                 gEnetGlobals.onError = kGetCommInterface;
  243.             } else {
  244.                 gEnetGlobals.onError = kReset;
  245.             }
  246.             pb->usbOther = 0;
  247.             
  248.             noteError(kDrvName"- Getting Comm Class interface");            
  249.             if(immediateError(configerr = USBNewInterfaceRef(pb)))
  250.             {
  251.                 USBExpertFatalError(gEnetGlobals.deviceRef, configerr, gEnetGlobals.errorString, 0);
  252.                 configured = true;
  253.             }
  254.         
  255.         break;
  256.     
  257.         case kSetCommInterface:
  258.             StatusMessage(gEnetGlobals.deviceRef, kDrvName"- Comm. Interface Ref - ", pb->usbReference);
  259.             
  260.             /* Remember the interfaceRef */
  261.             gEnetGlobals.interfaceRef = pb->usbReference;
  262.             
  263.             /* Set the interface (Comm) */
  264.             pb->usb.cntl.BMRequestType = USBMakeBMRequestType(kUSBNone, kUSBStandard, kUSBInterface);                        
  265.             pb->usb.cntl.BRequest = kUSBRqSetInterface;
  266.             pb->usb.cntl.WValue = 0;
  267.             pb->usb.cntl.WIndex = gEnetGlobals.interfacenum;
  268.             pb->usbReqCount = 0;
  269.             pb->usbBuffer = nil;
  270.             if (gEnetGlobals.retries > 0)
  271.             {
  272.                 gEnetGlobals.onError = kSetCommInterface;
  273.             } else {
  274.                 gEnetGlobals.onError = kReset;
  275.             }
  276.  
  277.             noteError(kDrvName"- Setting Comm Class interface");
  278.             if(immediateError(configerr = USBDeviceRequest(pb)))
  279.             {
  280.                 USBExpertFatalError(gEnetGlobals.deviceRef, configerr, gEnetGlobals.errorString, 0);
  281.             }
  282.             break;
  283.  
  284.         case kConfigureCommInterface:
  285.             
  286.             /* configure the Comm Class interface */
  287.             if (gEnetGlobals.retries > 0)
  288.             {
  289.                 gEnetGlobals.onError = kConfigureCommInterface;
  290.             } else {
  291.                 gEnetGlobals.onError = kReset;
  292.             }
  293.             
  294.             noteError(kDrvName"- Configuring the Comm Class interface");
  295.             if(immediateError(configerr = USBConfigureInterface(pb)))
  296.             {    
  297.                 USBExpertFatalError(gEnetGlobals.deviceRef, configerr, gEnetGlobals.errorString, 0);
  298.                 configured = true;
  299.             }
  300.             
  301.         break;
  302.         
  303.         case kGetInterruptEndpoint:
  304.             StatusMessage(gEnetGlobals.deviceRef, kDrvName"- Number of pipes in Interface - ", pb->usbOther);
  305.             
  306.             /* Get the Comm Class interrupt endpoint */
  307.             pb->usbFlags = kUSBIn;
  308.             pb->usbClassType = kUSBInterrupt;
  309.             if (gEnetGlobals.retries > 0)
  310.             {
  311.                 gEnetGlobals.onError = kGetInterruptEndpoint;
  312.             } else {
  313.                 gEnetGlobals.onError = kReset;
  314.             }
  315.             
  316.             noteError(kDrvName"- Finding the interrupt endpoint");
  317.             if(immediateError(configerr = USBFindNextPipe(pb)))
  318.             {    
  319.                 USBExpertFatalError(gEnetGlobals.deviceRef, configerr, gEnetGlobals.errorString, 0);
  320.                 configured = true;
  321.             }
  322.             
  323.         break;
  324.         
  325.         case kStartGetDescriptors:
  326.             StatusMessage(gEnetGlobals.deviceRef, kDrvName"- Interrupt In Ref - ", pb->usbReference);
  327.             
  328.             /* Interrupt Endpoint is open - remember the ref */
  329.             gEnetGlobals.interrupt = pb->usbReference;
  330.             
  331.             /* Set up to get the associated descriptors */
  332.             pb->usbReference = gEnetGlobals.interfaceRef;
  333.             pb->usb.cntl.WIndex = 0;
  334.             pb->usbReqCount = sizeof(gEnetGlobals.FuncDesc);
  335.             pb->usbBuffer = &gEnetGlobals.FuncDesc;
  336.             pb->usbOther = CS_Interface;
  337.             pb->usbFlags = 0;
  338.             if (gEnetGlobals.retries > 0)
  339.             {
  340.                 gEnetGlobals.onError = kStartGetDescriptors;
  341.             } else {
  342.                 gEnetGlobals.onError = kReset;
  343.             }
  344.             
  345.             noteError(kDrvName"- Set up for descriptors");
  346.             if(immediateError(configerr = USBFindNextAssociatedDescriptor(pb)))
  347.             {    
  348.                 USBExpertFatalError(gEnetGlobals.deviceRef, configerr, gEnetGlobals.errorString, 0);
  349.                 configured = true;
  350.             }
  351.             
  352.         break;
  353.         
  354.         case kGetDescriptors:
  355.             StatusMessage(gEnetGlobals.deviceRef, kDrvName"- Descriptor", pb->usb.cntl.WIndex);
  356.             LogData(kUSBNone, pb->usbActCount, (UInt8 *)pb->usbBuffer);
  357.             
  358.             if ((gEnetGlobals.FuncDesc.bDescriptorType == CS_Interface) && 
  359.                 (gEnetGlobals.FuncDesc.bDescriptorSubtype == Ethernet_Functional_Descriptor))
  360.             {    
  361.                 continue;
  362.             } else {
  363.             
  364.                 pb->usbRefcon--;                    // Need to come back here
  365.                 pb->usbFlags = 0;
  366.                 if (gEnetGlobals.retries > 0)
  367.                 {
  368.                     gEnetGlobals.onError = kGetDescriptors;
  369.                 } else {
  370.                     gEnetGlobals.onError = kReset;
  371.                 }
  372.             
  373.                 noteError(kDrvName"- Get next descriptor");
  374.                 if(immediateError(configerr = USBFindNextAssociatedDescriptor(pb)))
  375.                 {    
  376.                     USBExpertFatalError(gEnetGlobals.deviceRef, configerr, gEnetGlobals.errorString, 0);
  377.                     configured = true;
  378.                 }
  379.             }
  380.         break;
  381.         
  382.         case kSetDataConfig:
  383.         
  384.             pb->usb.cntl.WValue = 0;
  385.             pb->usb.cntl.WIndex = 0;
  386.             pb->usbReqCount = 0;
  387.             pb->usbActCount = 0;
  388.             pb->usbBuffer = nil;
  389.             pb->usbOther = 0xff;
  390.             continue;
  391.             
  392.         break;
  393.         
  394.         case kDataConfig:
  395.             
  396.             /* Need to find an interface with a data class in it */
  397.             pb->usbClassType = kUSBDataClass;
  398.             pb->usbSubclass = 0;
  399.             pb->usbProtocol = 0;
  400.             pb->usbReference = gEnetGlobals.deviceRef;        // Set it back to the device
  401.             pb->usbFlags = 0;
  402.             if (gEnetGlobals.retries > 0)
  403.             {
  404.                 gEnetGlobals.onError = kDataConfig;
  405.             } else {
  406.                 gEnetGlobals.onError = kReset;
  407.             }
  408.  
  409.             noteError(kDrvName"- Finding the Data Interface");
  410.             if(immediateError(configerr = USBFindNextInterface(pb)))
  411.             {
  412.                 USBExpertFatalError(gEnetGlobals.deviceRef, configerr, gEnetGlobals.errorString, 0);
  413.                 configured = true;
  414.             }
  415.             
  416.         break;
  417.         
  418.         case kGetDataInterface:
  419.             StatusMessage(gEnetGlobals.deviceRef, kDrvName"- Configuration Number - ", pb->usb.cntl.WValue);
  420.             StatusMessage(gEnetGlobals.deviceRef, kDrvName"- Interface Number - ", pb->usb.cntl.WIndex);
  421.             
  422.             /* Remember the interface number */
  423.             gEnetGlobals.interfacenum = pb->usb.cntl.WIndex;
  424.             
  425.             /* Get the interface reference number */
  426.             if (gEnetGlobals.retries > 0)
  427.             {
  428.                 gEnetGlobals.onError = kGetDataInterface;
  429.             } else {
  430.                 gEnetGlobals.onError = kReset;
  431.             }
  432.             pb->usbOther = 0;
  433.             
  434.             noteError(kDrvName"- Getting Data Class interface");
  435.             if(immediateError(configerr = USBNewInterfaceRef(pb)))
  436.             {
  437.                 USBExpertFatalError(gEnetGlobals.deviceRef, configerr, gEnetGlobals.errorString, 0);
  438.                 configured = true;
  439.             }
  440.         
  441.         break;
  442.  
  443.         case kConfigureDataInterface:
  444.             StatusMessage(gEnetGlobals.deviceRef, kDrvName"- Data Interface Ref - ", pb->usbReference);
  445.             
  446.             /* configure the Data Class interface */
  447.             if (gEnetGlobals.retries > 0)
  448.             {
  449.                 gEnetGlobals.onError = kConfigureDataInterface;
  450.             } else {
  451.                 gEnetGlobals.onError = kReset;
  452.             }
  453.             
  454.             noteError(kDrvName"- Configuring the Data Class interface");
  455.             if(immediateError(configerr = USBConfigureInterface(pb)))
  456.             {    
  457.                 USBExpertFatalError(gEnetGlobals.deviceRef, configerr, gEnetGlobals.errorString, 0);
  458.                 configured = true;
  459.             }
  460.             
  461.         break;
  462.             
  463.         case kGetBulkOutEndpoint:
  464.             StatusMessage(gEnetGlobals.deviceRef, kDrvName"- Number of pipes in Interface - ", pb->usbOther);
  465.             
  466.             if (pb->usbOther != 2)                    // need to find one with at least 2 (in and out)
  467.             {
  468.                 if (cnter++ > 1) break;
  469.                 
  470.                 pb->usbRefcon = kDataConfig;
  471.                 savOther++;
  472.                 pb->usbOther = savOther;
  473.                 continue;
  474.             }
  475.             
  476.             /* Find the out endpoint */
  477.             pb->usbFlags = kUSBOut;
  478.             pb->usbClassType = kUSBBulk;
  479.             pb->usbSubclass = 0;            /* Find the first one */
  480.             if (gEnetGlobals.retries > 0)
  481.             {
  482.                 gEnetGlobals.onError = kGetBulkOutEndpoint;
  483.             } else {
  484.                 gEnetGlobals.onError = kReset;
  485.             }
  486.             
  487.             noteError(kDrvName"- Finding the bulk out endpoint");
  488.             if(immediateError(configerr = USBFindNextPipe(pb)))
  489.             {    
  490.                 USBExpertFatalError(gEnetGlobals.deviceRef, configerr, gEnetGlobals.errorString, 0);
  491.                 configured = true;
  492.             }
  493.             
  494.         break;
  495.     
  496.         case kGetBulkInEndpoint:
  497.             StatusMessage(gEnetGlobals.deviceRef, kDrvName"- Bulk Out Endpoint - ", pb->usbReference);
  498.             
  499.             /* Out Endpoint is open - remember the ref */
  500.             gEnetGlobals.bulkOut = pb->usbReference;
  501.             
  502.             /* Find the in endpoint */
  503.             pb->usbFlags = kUSBIn;
  504.             pb->usbClassType = kUSBBulk;
  505.             pb->usbSubclass = 0;            /* Find the first one */
  506.             if (gEnetGlobals.retries > 0)
  507.             {
  508.                 gEnetGlobals.onError = kGetBulkInEndpoint;
  509.             } else {
  510.                 gEnetGlobals.onError = kReset;
  511.             }
  512.             
  513.             noteError(kDrvName"- Finding the bulk in endpoint");
  514.             if(immediateError(configerr = USBFindNextPipe(pb)))
  515.             {    
  516.                 USBExpertFatalError(gEnetGlobals.deviceRef, configerr, gEnetGlobals.errorString, 0);
  517.                 configured = true;
  518.             }
  519.             
  520.         break;
  521.     
  522.         case kConfigDone:
  523.             StatusMessage(gEnetGlobals.deviceRef, kDrvName"- Bulk In Endpoint - ", pb->usbReference);
  524.             
  525.             /* In Endpoint is open - remember the ref */
  526.             gEnetGlobals.bulkIn = pb->usbReference;
  527.             
  528.             // Let's go to task time just in case (if we're not already there - OT can be a bit ticklish)
  529.             if (CurrentExecutionLevel() == 0)
  530.                 continue;
  531.                     
  532.             StatusMessage(gEnetGlobals.deviceRef, "\pSwitching to task time", 0);
  533.             pb->usbReqCount = 0;
  534.             pb->usbFlags = kUSBTaskTimeFlag;                
  535.             USBDelay(pb);
  536.             
  537.         break;
  538.         
  539.         case kInstallDrvr:
  540.             pb->usbReqCount = 0;
  541.             pb->usbStatus = noErr;
  542.             pb->usbBuffer = nil;
  543.             pb->usbFlags = 0;
  544.             
  545.             if (CurrentExecutionLevel() != 0)
  546.                 StatusMessage(gEnetGlobals.deviceRef, "\pCaution - Installing OT driver at non-task time", 0);
  547.                 
  548.             configerr = InstallShimDrvr(ConnID);            // Could use Product ID string but for now we don't
  549.             if (configerr == noErr)
  550.             {
  551.                 StartStatusMonitor(gEnetGlobals.interrupt);
  552.                 
  553.                 // device is fully configured, now we can start reading/writing to the bulk endpoints
  554.                 syncPB.usbStatus = kAvailableStatus;
  555.                 StatusMessage(gEnetGlobals.deviceRef, kDrvName"- Configuration complete.", 0);
  556.         
  557.             } else {
  558.                 StatusMessage(gEnetGlobals.deviceRef, kDrvName"- Can't install driver.", configerr);
  559.             }
  560.             configured = true;
  561.         break;
  562.     
  563.         default:
  564.             noteError(kDrvName"- Internal Error unused case in Configuration handler");            
  565.             StatusMessage(gEnetGlobals.deviceRef, gEnetGlobals.errorString, (pb->usbRefcon-1));
  566.             configured = true;
  567.             configerr = -1;
  568.         break;
  569.     }
  570.     break;    /* only execute once, unless continue used */
  571.     }while(1);    /* so case can be reentered with a continue */
  572. }
  573.  
  574. /************************************************************************************/
  575. //
  576. //    ResetInterruptPB
  577. //
  578. //    Re-initialize the interrupt PB.
  579. //
  580. /************************************************************************************/
  581.  
  582. static void ResetInterruptPB(USBPB *pb)
  583. {
  584.     pb->usbReqCount = sizeof(statusData);
  585.     pb->usbBuffer = &statusData;
  586.     pb->usbStatus = noErr;
  587. }
  588.  
  589. /************************************************************************************/
  590. //
  591. //    interruptCompletion
  592. //
  593. //    Interrupt completion handler.
  594. //
  595. /************************************************************************************/
  596.  
  597. static void interruptCompletion(USBPB *pb)
  598. {
  599.     OSStatus    err;
  600.     UInt16        Notif;
  601.     UInt32        upspeed;
  602.     UInt16        *ups = (UInt16 *)&upspeed;
  603.     UInt32        dwnspeed;
  604.     UInt16        *dwns = (UInt16 *)&dwnspeed;
  605.     ShimEnetGlobals    *globals = gGlobals;
  606.     
  607.     TraceMessage(0, kDrvName"- Entering interruptCompletion");
  608.     
  609.     if (pb->usbStatus != kUSBAbortedError)    // are we being asked to quit?
  610.     {
  611.         if (pb->usbStatus != noErr)
  612.         {
  613.             StatusMessage(gEnetGlobals.deviceRef, kDrvName"- interruptCompletion: Error ", pb->usbStatus);
  614.             if (pb->usbStatus == kUSBEndpointStallErr)
  615.             {
  616.                 ClearDevice();
  617.             }
  618.             USBClearPipeStallByReference(gEnetGlobals.interrupt);
  619.             
  620.             Intrretries++;
  621.             if (Intrretries > 10)
  622.                 return;                    // we'll just give up for now
  623.                 
  624.             DoDelay();
  625.  
  626.         } else {
  627.             Intrretries = 0;
  628.             TraceMessage(0, kDrvName"- Interrupt received");
  629.             LogData(kUSBNone, pb->usbActCount, pb->usbBuffer);
  630.     
  631.             if (pb->usbActCount > 2)
  632.             {
  633.                 Notif = (statusData[0] & 0x00FF);
  634.                 switch (Notif)
  635.                 {
  636.                     case kNetwork_Connection:
  637.                         (*gGlobals->ShimAsync) (gGlobals->ShimRef, EnetShim_Link, (HostToUSBWord(statusData[1])), 0);
  638.                         break;
  639.                         
  640.                     case kConnection_Speed_Change:
  641.                         ups[0] = statusData[4];
  642.                         ups[1] = statusData[5];
  643.                         dwns[0] = statusData[6];
  644.                         dwns[1] = statusData[7];
  645.                         (*gGlobals->ShimAsync) (gGlobals->ShimRef, EnetShim_Speed, (HostToUSBLong(upspeed)), (HostToUSBLong(dwnspeed)));
  646.                         break;
  647.                 
  648.                     default:
  649.                         
  650.                         break;
  651.                 }
  652.             }
  653.         }
  654.     }
  655.         
  656.     ResetInterruptPB(pb);
  657.  
  658.     if(immediateError(err = USBIntRead(pb)))
  659.     {
  660.         StatusMessage(gEnetGlobals.deviceRef, kDrvName"- interruptCompletion: Couldn't queue interrupt read!", err);
  661.     }    
  662. }
  663.  
  664. /************************************************************************************/
  665. //
  666. //    StartStatusMonitor
  667. //
  668. //    Kick off the interrupt mechanism.
  669. //
  670. /************************************************************************************/
  671.  
  672. static void StartStatusMonitor(USBPipeRef interruptPipe)
  673. {
  674.     USBPB        *pb = &interruptPB;
  675.     OSStatus    err;
  676.     
  677.     TraceMessage(0, kDrvName"- Entering StartStatusMonitor");
  678.     
  679.     InitializePB(pb, interruptPipe, interruptCompletion);
  680.  
  681.     ResetInterruptPB(pb);
  682.  
  683.     if(immediateError(err = USBIntRead(pb)))
  684.     {
  685.         StatusMessage(gEnetGlobals.deviceRef, kDrvName"- StartStatusMonitor: Couldn't start interrupt read!", err);
  686.     }        
  687.  
  688. }
  689.  
  690. /************************************************************************************/
  691. //
  692. //    syncCompletion
  693. //
  694. //    Completion handler for all sync (setup) requests.
  695. //
  696. /************************************************************************************/
  697.  
  698. static void syncCompletion(USBPB *pb)
  699. {
  700.  
  701.     TraceMessage(0, kDrvName"- Entering syncCompletion");
  702.  
  703.     if (pb->usbStatus != noErr)
  704.     {
  705.         USBExpertFatalError(gEnetGlobals.deviceRef, pb->usbStatus, kDrvName"- syncCompletion: Error for bRequest", pb->usb.cntl.BRequest);
  706.         if (pb->usbStatus == kUSBEndpointStallErr)
  707.         {
  708. //            ClearDevice();
  709.         }
  710.         USBClearPipeStallByReference(pb->usbReference);
  711.     }
  712.         
  713.     pb->usbStatus = kAvailableStatus;
  714. }
  715.  
  716. /************************************************************************************/
  717. //
  718. //    USBReadData
  719. //
  720. //    Transfers data to the applications buffer.
  721. //
  722. /************************************************************************************/
  723.  
  724. UInt32 USBReadData(UInt8 *buf, UInt32 size)
  725. {
  726.     UInt16    actlength;
  727.     UInt8    *flplen = (UInt8 *)&actlength;
  728.     UInt32    bufindx;
  729.     UInt8    *inbuf;
  730.     
  731.     TraceMessage(0, kDrvName"- Entering USBReadData");
  732.     
  733.     inbuf = RemoveFromRcvList(&bufindx);
  734.  
  735.     if (inbuf == nil)
  736.     {
  737.         actlength = 0;
  738.     } else {
  739.         flplen[0] = inbuf[1];
  740.         flplen[1] = inbuf[0];
  741.         if (size < actlength)
  742.         {
  743.             actlength = 0;
  744.         } else {
  745.             BlockMoveData(&inbuf+2, buf, actlength);
  746.         }
  747.     }
  748.     
  749.     return actlength;
  750.     
  751. }
  752.  
  753. /************************************************************************************/
  754. //
  755. //    USBGetAddress
  756. //
  757. //    Gets the ethernet address from the hardware (actually the functional descriptor).
  758. //
  759. /************************************************************************************/
  760.  
  761. void USBGetAddress(UInt32 *count, UInt8 *buf)
  762. {
  763.     
  764.     TraceMessage(0, kDrvName"- Entering USBGetAddress");
  765.     
  766.     *count = 6;
  767.     BlockMoveData(&gEnetGlobals.bMACAddress, buf, 6);
  768.     
  769. }
  770.  
  771. /************************************************************************************/
  772. //
  773. //    USBSetisr
  774. //
  775. //    Sets the isr and cookie for the receiver
  776. //
  777. /************************************************************************************/
  778.  
  779. void USBSetisr(ProcPtr isr, void *cookie)
  780. {
  781.     
  782.     TraceMessage(0, kDrvName"- Entering USBSetisr");
  783.     
  784.     StatusMessage(gEnetGlobals.deviceRef, kDrvName"- isr - ", (UInt32)isr);
  785.     StatusMessage(gEnetGlobals.deviceRef, kDrvName"- cookie - ", (UInt32)cookie);
  786.     
  787.     gGlobals->isr = isr;
  788.     gGlobals->cookie = (UInt32)cookie;
  789. }
  790.  
  791. /************************************************************************************/
  792. //
  793. //    USBSetAddress
  794. //
  795. //    Sets the temporary ethernet address.
  796. //
  797. /************************************************************************************/
  798.  
  799. OSStatus USBSetAddress(UInt32 count, UInt8 *buf)
  800. {
  801. #pragma unused (count, buf)
  802.  
  803.     OSStatus err = noErr;
  804.     
  805.     TraceMessage(0, kDrvName"- Entering USBSetAddress");
  806.     
  807.     // Not supported by this driver
  808.     err = ioErr;
  809.     
  810.     return err;
  811. }
  812.  
  813. /************************************************************************************/
  814. //
  815. //    multicastHandler
  816. //
  817. //    Completion handler for USBSetMulticastFilters.
  818. //
  819. /************************************************************************************/
  820.  
  821. static void multicastHandler(USBPB *pb)
  822. {
  823.  
  824.     TraceMessage(0, kDrvName"- Entering multicastHandler");
  825.  
  826.     if (pb->usbStatus != noErr)
  827.     {
  828.         StatusMessage(gEnetGlobals.deviceRef, kDrvName"- multicastHandler: Error", pb->usbStatus);
  829.         // Return an async error
  830.         (*gGlobals->ShimAsync) (gGlobals->ShimRef, EnetShim_Error, EnetHAL_SetMulticastFilters, pb->usbStatus);
  831.     }
  832.  
  833.     PoolDeallocate(pb->usbBuffer);
  834. }
  835.  
  836. /************************************************************************************/
  837. //
  838. //    USBSetMulticastFilters
  839. //
  840. //    Sets the multicast filters.
  841. //
  842. /************************************************************************************/
  843.  
  844. OSStatus USBSetMulticastFilters(UInt32 numFilters, EnetAddressListPtr list)
  845. {
  846.     OSStatus             err = noErr;
  847.     UInt16                countfilters=0;
  848.     UInt16                filterLen;
  849.     UInt16                i, indx=0;
  850.     EnetAddressListPtr    x;
  851.     UInt8                *buf;
  852.     
  853.     TraceMessage(0, kDrvName"- Entering USBSetMulticastFilters");
  854.     
  855.     filterLen = numFilters*sizeof(EnetAddress);
  856.     buf = PoolAllocateResident(filterLen, true);
  857.     
  858.     for (x=list; x; x=x->next)
  859.     {
  860.         countfilters += 1;
  861.         for (i=0; i<=sizeof(EnetAddress)-1; i++)
  862.         {
  863.             buf[indx++] = x->address[i];
  864.             if (indx > filterLen)
  865.                 break;
  866.         }
  867.         if (indx > filterLen)
  868.         {
  869.             StatusMessage(gEnetGlobals.deviceRef, kDrvName"- Filter buffer overrun", indx);
  870.             break;
  871.         }
  872.     }
  873.     
  874.     if (numFilters != countfilters)
  875.     {
  876.         StatusMessage(gEnetGlobals.deviceRef, kDrvName"- Filters do not match", 0);
  877.         StatusMessage(gEnetGlobals.deviceRef, kDrvName"- Number from OT = ", numFilters);
  878.         StatusMessage(gEnetGlobals.deviceRef, kDrvName"- Number calculated = ", countfilters);
  879.         StatusMessage(gEnetGlobals.deviceRef, kDrvName"- Filters", (UInt32)list);
  880.         if (list != nil)
  881.             LogData(kUSBNone, 32, (UInt8 *)list);
  882.     }
  883.         
  884.     InitializePB(&gEnetGlobals.pb, gEnetGlobals.deviceRef, multicastHandler);
  885.     gEnetGlobals.pb.pbVersion = kUSBCurrentPBVersion;
  886.     gEnetGlobals.pb.usb.cntl.BMRequestType = USBMakeBMRequestType(kUSBOut, kUSBVendor, kUSBDevice);            
  887.     
  888.     gEnetGlobals.pb.usb.cntl.BRequest = kSet_Ethernet_Multicast_Filter;
  889.     gEnetGlobals.pb.usbReference = gEnetGlobals.deviceRef;
  890.     gEnetGlobals.pb.usbFlags = 0;
  891.     gEnetGlobals.pb.usbClassType = 0;
  892.     gEnetGlobals.pb.usb.cntl.WValue = numFilters; 
  893.     gEnetGlobals.pb.usb.cntl.WIndex = 0;
  894.     gEnetGlobals.pb.usbReqCount = indx;
  895.     gEnetGlobals.pb.usbBuffer = buf;
  896.  
  897.     noteError(kDrvName"- Driver setting Multicast Filters");    
  898.     if(immediateError(err = USBDeviceRequest(&gEnetGlobals.pb)))
  899.     {
  900.         USBExpertFatalError(gEnetGlobals.deviceRef, err, gEnetGlobals.errorString, 0);
  901.     }
  902.     
  903.     if (err > noErr)
  904.         err = noErr;
  905.     return err;
  906. }
  907.  
  908. /************************************************************************************/
  909. //
  910. //    packetfilterHandler
  911. //
  912. //    Completion handler for USBSetPacketfilter.
  913. //
  914. /************************************************************************************/
  915.  
  916. static void packetfilterHandler(USBPB *pb)
  917. {
  918.  
  919.     TraceMessage(0, kDrvName"- Entering packetfilterHandler");
  920.  
  921.     if (pb->usbStatus != noErr)
  922.     {
  923.         StatusMessage(gEnetGlobals.deviceRef, kDrvName"- packetfilterHandler: Error", pb->usbStatus);
  924.         // Return an async error
  925.         (*gGlobals->ShimAsync) (gGlobals->ShimRef, EnetShim_Error, EnetHAL_SetMulticastFilters, pb->usbStatus);
  926.     }
  927.  
  928. }
  929.  
  930. /************************************************************************************/
  931. //
  932. //    USBSetPacketFilter
  933. //
  934. //    Sets the packet filter.
  935. //
  936. /************************************************************************************/
  937.  
  938. OSStatus USBSetPacketFilter(UInt16 *filter)
  939. {
  940.     OSStatus err = noErr;
  941.     
  942.     TraceMessage(0, kDrvName"- Entering USBSetPacketFilter");
  943.     
  944.     InitializePB(&gEnetGlobals.pb, gEnetGlobals.deviceRef, packetfilterHandler);
  945.     gEnetGlobals.pb.pbVersion = kUSBCurrentPBVersion;
  946.     gEnetGlobals.pb.usb.cntl.BMRequestType = USBMakeBMRequestType(kUSBOut, kUSBVendor, kUSBDevice);            
  947.     
  948.     gEnetGlobals.pb.usb.cntl.BRequest = kSet_Ethernet_Packet_Filter;
  949.     gEnetGlobals.pb.usbReference = gEnetGlobals.deviceRef;
  950.     gEnetGlobals.pb.usbFlags = 0;
  951.     gEnetGlobals.pb.usbClassType = 0;
  952.     gEnetGlobals.pb.usb.cntl.WValue = *filter; 
  953.     gEnetGlobals.pb.usb.cntl.WIndex = 0; 
  954.     gEnetGlobals.pb.usbReqCount = 0;
  955.     gEnetGlobals.pb.usbBuffer = nil;
  956.  
  957.     noteError(kDrvName"- Driver setting packet filter");    
  958.     if(immediateError(err = USBDeviceRequest(&gEnetGlobals.pb)))
  959.     {
  960.         USBExpertFatalError(gEnetGlobals.deviceRef, err, gEnetGlobals.errorString, 0);
  961.     }
  962.     
  963.     if (err > noErr)
  964.         err = noErr;
  965.     return err;
  966. }
  967.  
  968. /************************************************************************************/
  969. //
  970. //    TimeoutPrevRequest
  971. //
  972. //    Timeout for all sync. requests.
  973. //
  974. /************************************************************************************/
  975.  
  976. Boolean TimeoutPrevRequest(void)
  977. {
  978.     USBPB        *pb = &syncPB;
  979.     AbsoluteTime    startTime;
  980.     Duration        elapsedTime;
  981.  
  982.     if (pb->usbStatus == kAvailableStatus)
  983.         return false;
  984.     
  985.     startTime = UpTime();
  986.  
  987.     while (pb->usbStatus != kAvailableStatus){
  988.         elapsedTime = AbsoluteDeltaToDuration(UpTime(), startTime);
  989.         if (elapsedTime < 0) elapsedTime = elapsedTime/(-1000);      // make sure it's in milliseconds
  990.         if (elapsedTime > 100*durationMillisecond){
  991.             StatusMessage(gEnetGlobals.deviceRef, kDrvName"- TimeoutPrevRequest: Timeout - aborting", 0);
  992.             USBAbortPipeByReference(pb->usbReference);
  993.             return true;
  994.         }
  995.     }
  996.     return false;
  997. }
  998.  
  999. /************************************************************************************/
  1000. //
  1001. //    TimeoutStallRequest
  1002. //
  1003. //    Timeout for all stall clear requests.
  1004. //
  1005. /************************************************************************************/
  1006.  
  1007. Boolean TimeoutStallRequest(void)
  1008. {
  1009.     USBPB            *pb = &stallPB;
  1010.     AbsoluteTime    startTime;
  1011.     Duration        elapsedTime;
  1012.  
  1013.     if (pb->usbStatus == kAvailableStatus)
  1014.         return false;
  1015.     
  1016.     startTime = UpTime();
  1017.  
  1018.     while (pb->usbStatus != kAvailableStatus){
  1019.         elapsedTime = AbsoluteDeltaToDuration(UpTime(), startTime);
  1020.         if (elapsedTime < 0) elapsedTime = elapsedTime/(-1000);      // make sure it's in milliseconds
  1021.         if (elapsedTime > 100*durationMillisecond){
  1022.             StatusMessage(gEnetGlobals.deviceRef, kDrvName"- TimeoutStallRequest: Timeout - aborting", 0);
  1023.             USBAbortPipeByReference(pb->usbReference);
  1024.             return true;
  1025.         }
  1026.     }
  1027.     return false;
  1028. }
  1029.  
  1030. /************************************************************************************/
  1031. //
  1032. //    TimeoutDelayRequest
  1033. //
  1034. //    Timeout for delay requests.
  1035. //
  1036. /************************************************************************************/
  1037.  
  1038. Boolean TimeoutDelayRequest(void)
  1039. {
  1040.     USBPB            *pb = &delayPB;
  1041.     AbsoluteTime    startTime;
  1042.     Duration        elapsedTime;
  1043.  
  1044.     if (pb->usbStatus == kAvailableStatus)
  1045.         return false;
  1046.     
  1047.     startTime = UpTime();
  1048.  
  1049.     while (pb->usbStatus != kAvailableStatus){
  1050.         elapsedTime = AbsoluteDeltaToDuration(UpTime(), startTime);
  1051.         if (elapsedTime < 0) elapsedTime = elapsedTime/(-1000);      // make sure it's in milliseconds
  1052.         if (elapsedTime > 100*durationMillisecond){
  1053.             return true;
  1054.         }
  1055.     }
  1056.     return false;
  1057. }
  1058.  
  1059. /************************************************************************************/
  1060. //
  1061. //    USBEnetDriverEntry
  1062. //
  1063. //    Initializes and starts the whole show.
  1064. //
  1065. /************************************************************************************/
  1066.  
  1067. OSStatus USBEnetDriverEntry(USBDeviceRef device, USBDeviceDescriptor *desc)
  1068. {
  1069. static Boolean                 beenThereDoneThat = false;
  1070. static USBDeviceDescriptor     ourDeviceDescriptor;
  1071. UInt16    i;
  1072.  
  1073. //    DebugMessage(kDrvName"- Entering EnetDriverEntry - Sync. point");
  1074.     TraceMessage(0, kDrvName"- Entering EnetDriverEntry");
  1075.         
  1076.     if(beenThereDoneThat)
  1077.     {
  1078.         StatusMessage(device, kDrvName"- USBEnetDriverEntry: Driver called second time", 0);
  1079.         return -1;
  1080.     }
  1081.     beenThereDoneThat = true;
  1082.     
  1083.     ourDeviceDescriptor = *desc;
  1084.     gEnetGlobals.deviceDescriptor = &ourDeviceDescriptor;
  1085.     gEnetGlobals.deviceRef = device;
  1086.     
  1087.     InitializePB(&syncPB, device, syncCompletion);
  1088.     InitializePB(&stallPB, device, stallHandler);
  1089.     stallPB.usbStatus = kAvailableStatus;
  1090.     InitializePB(&delayPB, device, delayHandler);
  1091.     delayPB.usbStatus = kAvailableStatus;
  1092.  
  1093.     InitializePB(&gEnetGlobals.pb, device, ConfigurationHandler);
  1094.     gEnetGlobals.pb.usbRefcon = kCommConfig;        // Where we start from (kReset used for errors)
  1095.     gEnetGlobals.pb.usbBuffer = nil;
  1096.  
  1097.     gEnetGlobals.retries = 3;                        // Let's keep it reasonable for now
  1098.     
  1099.     for (i=0; i<kNumInBufs; i++)
  1100.     {
  1101.         gGlobals->inBuf[i].avail = 0;                                    //    clear it
  1102.         gGlobals->inBuf[i].bufPB.usbBuffer = gGlobals->inBuf[i].Buffer;    //    assign input buffer
  1103.         gGlobals->inBuf[i].qLink = nil;
  1104.         gGlobals->inBuf[i].indx = i;
  1105.     }
  1106.     
  1107.     gGlobals->rcvq.qFlags = 0;                                            // Clear the receive queue
  1108.     gGlobals->rcvq.qHead = nil;
  1109.     gGlobals->rcvq.qTail = nil;
  1110.     
  1111.     for (i=0; i<kNumOutBufs; i++)                                        // We use the same buffer struct
  1112.     {                                                                    // but no send queue is used
  1113.         gGlobals->outBuf[i].avail = kAvailable;                                //    make it available
  1114.         gGlobals->outBuf[i].bufPB.usbBuffer = gGlobals->outBuf[i].Buffer;    //    assign output buffer
  1115.         gGlobals->outBuf[i].qLink = nil;
  1116.         gGlobals->outBuf[i].indx = i;
  1117.     }
  1118.     
  1119.     CheckUSBVersion();
  1120.     ConfigurationHandler(&gEnetGlobals.pb);
  1121.     
  1122.     if (configerr == 1)                        // pending's ok
  1123.     {
  1124.         return noErr;
  1125.     } else {
  1126.         return configerr;
  1127.     }
  1128. }
  1129.  
  1130. /************************************************************************************/
  1131. //
  1132. //    InitializePB
  1133. //
  1134. //    Initial a parameter block.
  1135. //
  1136. /************************************************************************************/
  1137.  
  1138. static void InitializePB(USBPB *pb, USBDeviceRef ref, USBCompletion handler)
  1139. {
  1140.     pb->pbVersion = kUSBCurrentPBVersion;
  1141.     pb->pbLength = sizeof(*pb);
  1142.     pb->usbReference = ref;
  1143.     pb->usbCompletion = handler;
  1144.     pb->usbStatus = noErr;
  1145.     
  1146. }
  1147.  
  1148. /************************************************************************************/
  1149. //
  1150. //    readCompletion
  1151. //
  1152. //    Completion handler for USB reads.
  1153. //
  1154. /************************************************************************************/
  1155.  
  1156. void readCompletion(USBPB *pb)
  1157. {
  1158.  
  1159.     TraceMessage(0,kDrvName"- Entering readCompletion");
  1160.     
  1161.     if (pb->usbStatus != kUSBAbortedError)    // are we being asked to quit?
  1162.     {
  1163.         if (pb->usbStatus == noErr)
  1164.         {            
  1165.             if (pb->usbActCount > 2)
  1166.             {
  1167.                 TraceMessage(0,kDrvName"- readCompletion live data");
  1168.                 LogData(kUSBIn, pb->usbActCount, pb->usbBuffer);
  1169.                 
  1170.                 AddToRcvList(pb->usbRefcon);
  1171.                 // Let's tell someone
  1172.                 StatusMessage(gEnetGlobals.deviceRef, kDrvName"- Calling with isr - ", (UInt32)gGlobals->isr);
  1173.                 StatusMessage(gEnetGlobals.deviceRef, kDrvName"- Calling with cookie - ", gGlobals->cookie);
  1174.                 if (gGlobals->isr)
  1175.                     (*gGlobals->isr) (gGlobals->cookie);
  1176.             } else {
  1177.                 StatusMessage(gEnetGlobals.deviceRef, kDrvName"- packet discarded, length = ", pb->usbActCount);
  1178.                 USBStartReadPolling(pb->usbRefcon);
  1179.             }
  1180.         } else {
  1181.             StatusMessage(gEnetGlobals.deviceRef, kDrvName"- readCompletion: Error ", pb->usbStatus);
  1182.                 
  1183.             if ((pb->usbStatus != kUSBUnderRunErr) && errCount++ < 10)
  1184.                 StatusMessage(gEnetGlobals.deviceRef, kDrvName"- readCompletion: Error ", pb->usbStatus);
  1185.                 
  1186.             if (pb->usbStatus == kUSBEndpointStallErr)
  1187.             {
  1188. //                ClearDevice();
  1189.             }
  1190.             USBClearPipeStallByReference(gEnetGlobals.bulkIn);
  1191.             
  1192.             LogData(kUSBIn, pb->usbActCount, pb->usbBuffer);
  1193.             
  1194.             if (pb->usbActCount > 2)
  1195.             {
  1196.                 AddToRcvList(pb->usbRefcon);
  1197.                 // Let's tell someone
  1198.                 StatusMessage(gEnetGlobals.deviceRef, kDrvName"- Calling with isr - ", (UInt32)gGlobals->isr);
  1199.                 StatusMessage(gEnetGlobals.deviceRef, kDrvName"- Calling with cookie - ", gGlobals->cookie);
  1200.                 if (gGlobals->isr)
  1201.                     (*gGlobals->isr) (gGlobals->cookie);
  1202.             } else {
  1203.                 StatusMessage(gEnetGlobals.deviceRef, kDrvName"- packet discarded, length = ", pb->usbActCount);
  1204.                 USBStartReadPolling(pb->usbRefcon);
  1205.             }
  1206.         }        
  1207.     }
  1208. }
  1209.  
  1210. /************************************************************************************/
  1211. //
  1212. //    USBStartupRead
  1213. //
  1214. //    Start the USB read mechanism for each buffer.
  1215. //
  1216. /************************************************************************************/
  1217.  
  1218. void USBStartupRead(void)
  1219. {
  1220.     UInt32 bufInindx;
  1221.     
  1222.     TraceMessage(0,kDrvName"- Entering USBStartupRead");
  1223.     
  1224.     // Find a buffer
  1225.     for (bufInindx=0; bufInindx<kNumInBufs; bufInindx++)
  1226.     {
  1227.         USBStartReadPolling(bufInindx);
  1228.     }
  1229.     
  1230. }
  1231.  
  1232. /************************************************************************************/
  1233. //
  1234. //    USBStartReadPolling
  1235. //
  1236. //    Start the USB read mechanism.
  1237. //
  1238. /************************************************************************************/
  1239.  
  1240. void USBStartReadPolling(UInt32 bufindx)
  1241. {
  1242.     OSStatus status;
  1243.     
  1244.     TraceMessage(0,kDrvName"- Entering USBStartReadPolling");
  1245.     
  1246.     if (gEnetGlobals.bulkIn)
  1247.     {
  1248.         gGlobals->inBuf[bufindx].avail = 0;
  1249.         
  1250.         InitializePB(&gGlobals->inBuf[bufindx].bufPB, gEnetGlobals.bulkIn, readCompletion);
  1251.         gGlobals->inBuf[bufindx].bufPB.usbRefcon = bufindx;
  1252.         gGlobals->inBuf[bufindx].bufPB.usbReqCount = kBufferSize+2;
  1253.         if(immediateError(status = USBBulkRead(&gGlobals->inBuf[bufindx].bufPB)))
  1254.         {
  1255.             USBExpertFatalError(gEnetGlobals.deviceRef, status, kDrvName"- USBStartReadPolling: Couldn't start read", bufindx);
  1256.             return;
  1257.         }
  1258.     }
  1259. }
  1260.  
  1261. /************************************************************************************/
  1262. //
  1263. //    USBStopReadPolling
  1264. //
  1265. //    You guessed it stop the USB read mechanism.
  1266. //
  1267. /************************************************************************************/
  1268.  
  1269. void USBStopReadPolling()
  1270. {
  1271.     StatusMessage(gEnetGlobals.deviceRef, kDrvName"- USBStopReadPolling: Aborting Bulk-in pipe", 0);
  1272.  
  1273.     if (gEnetGlobals.bulkIn)
  1274.     {
  1275.         USBAbortPipeByReference(gEnetGlobals.bulkIn);
  1276.         gGlobals->rcvq.qHead = nil;
  1277.         gGlobals->rcvq.qTail = nil;
  1278.     }
  1279. }
  1280.  
  1281. /************************************************************************************/
  1282. //
  1283. //    writeCompletion
  1284. //
  1285. //    USB write completion handler.
  1286. //
  1287. /************************************************************************************/
  1288.  
  1289. void writeCompletion(USBPB *pb)
  1290. {
  1291.     ShimEnetGlobals    *globals = gGlobals;
  1292.     
  1293.     TraceMessage(0, kDrvName"- Entering writeCompletion");
  1294.     
  1295.     if (pb->usbStatus != kUSBAbortedError)    // are we being asked to quit?
  1296.     {
  1297.         if (pb->usbStatus != noErr) 
  1298.         {
  1299.             StatusMessage(gEnetGlobals.deviceRef, kDrvName"- writeCompletion: Error", pb->usbStatus);
  1300.             
  1301.             // Return an async error
  1302.             (*gGlobals->ShimAsync) (gGlobals->ShimRef, EnetShim_Error, EnetHAL_Write, pb->usbStatus);
  1303.             
  1304.             if (pb->usbStatus == kUSBEndpointStallErr)
  1305.             {
  1306.                 ClearDevice();
  1307.             }
  1308.             USBClearPipeStallByReference(pb->usbReference);
  1309.         }
  1310.     }
  1311.     gGlobals->outBuf[pb->usbRefcon].avail = kAvailable;
  1312. }
  1313.  
  1314. /************************************************************************************/
  1315. //
  1316. //    USBEnetWrite
  1317. //
  1318. //    USB Ethernet write routine.
  1319. //
  1320. /************************************************************************************/
  1321.  
  1322. OSStatus USBEnetWrite(UInt32 count, UInt8 *buf)
  1323. {
  1324.     OSStatus     status = noErr;
  1325.     UInt8        *datalen = (unsigned char *)&count;
  1326.     UInt32        bufindx;
  1327.     Boolean        writeok = false;
  1328.     
  1329.     TraceMessage(0, kDrvName"- Entering USBEnetWrite");
  1330.     
  1331.     // Find a buffer
  1332.     for (bufindx=0; bufindx<kNumOutBufs; bufindx++)
  1333.     {
  1334.         if (gGlobals->outBuf[bufindx].avail == kAvailable)
  1335.         {
  1336.             writeok = true;
  1337.             gGlobals->outBuf[bufindx].avail = kUnavailable;
  1338.             break;
  1339.         }
  1340.     }
  1341.     if (!writeok)
  1342.     {
  1343.         StatusMessage(gEnetGlobals.deviceRef, kDrvName"- USBEnetWrite: No buffers available", bufindx);
  1344.         status = ioErr;
  1345.         gGlobals->outBuf[bufindx].avail = kAvailable;
  1346.     } else { 
  1347.         if (!gEnetGlobals.bulkOut)
  1348.         {
  1349.             status = ioErr;
  1350.             gGlobals->outBuf[bufindx].avail = kAvailable;
  1351.         } else {
  1352.             if ((count+2) > kBufferSize)
  1353.             {
  1354.                 status = ioErr;
  1355.                 StatusMessage(gEnetGlobals.deviceRef, kDrvName"- USBEnetWrite: Data length error", count);
  1356.                 gGlobals->outBuf[bufindx].avail = kAvailable;
  1357.             } else {            
  1358.                 BlockMoveData(buf, &gGlobals->outBuf[bufindx].Buffer[2], count);
  1359.                 gGlobals->outBuf[bufindx].Buffer[0] = datalen[3];
  1360.                 gGlobals->outBuf[bufindx].Buffer[1] = datalen[2];
  1361.                 InitializePB(&gGlobals->outBuf[bufindx].bufPB, gEnetGlobals.bulkOut, writeCompletion);
  1362.                 gGlobals->outBuf[bufindx].bufPB.usbRefcon = bufindx;
  1363.                 gGlobals->outBuf[bufindx].bufPB.usbReqCount = count+2;
  1364.         
  1365.                 LogData(kUSBOut, gGlobals->outBuf[bufindx].bufPB.usbReqCount, gGlobals->outBuf[bufindx].bufPB.usbBuffer);
  1366.         
  1367.                 if(immediateError(status = USBBulkWrite(&gGlobals->outBuf[bufindx].bufPB)))
  1368.                 {
  1369.                     StatusMessage(gEnetGlobals.deviceRef, kDrvName"- USBEnetWrite: Couldn't start write", status);
  1370.                     gGlobals->outBuf[bufindx].avail = kAvailable;
  1371.                 } else {
  1372.                     status = noErr;
  1373.                 }
  1374.             }
  1375.         }
  1376.     }
  1377.     return status;
  1378. }
  1379.  
  1380. /************************************************************************************/
  1381. //
  1382. //    KillUSBIO
  1383. //
  1384. //    Kill all USB io operations in progress.
  1385. //
  1386. /************************************************************************************/
  1387.  
  1388. void KillUSBIO(void)
  1389. {
  1390.     
  1391.     TraceMessage(0, kDrvName"- Entering KillUSBIO");
  1392.     StatusMessage(gEnetGlobals.deviceRef, kDrvName"- KillUSBIO: Killing all USB IO", 0);
  1393.  
  1394.     if (gEnetGlobals.bulkIn){
  1395.         USBAbortPipeByReference(gEnetGlobals.bulkIn);
  1396.         gEnetGlobals.bulkIn = nil;
  1397.     }
  1398.     if (gEnetGlobals.bulkOut){
  1399.         USBAbortPipeByReference(gEnetGlobals.bulkOut);
  1400.         gEnetGlobals.bulkOut = nil;
  1401.     }
  1402.     if (gEnetGlobals.interrupt){
  1403.         USBAbortPipeByReference(gEnetGlobals.interrupt);
  1404.         gEnetGlobals.interrupt = nil;
  1405.     }
  1406.     if (gGlobals)
  1407.     {
  1408.         gGlobals->rcvq.qHead = nil;
  1409.         gGlobals->rcvq.qTail = nil;
  1410.     }
  1411. }
  1412.  
  1413. /************************************************************************************/
  1414. //
  1415. //    DoDelay
  1416. //
  1417. //    Set up to do a USB delay.
  1418. //
  1419. /************************************************************************************/
  1420.  
  1421. void DoDelay(void)
  1422. {
  1423.     
  1424.     TraceMessage(0, kDrvName"- Entering DoDelay");
  1425.     
  1426.     if (TimeoutDelayRequest())
  1427.         return;
  1428.             
  1429.     delayPB.usbStatus = noErr;
  1430.     delayPB.usbReference = gEnetGlobals.deviceRef;
  1431.     delayPB.usbRefcon = 1;
  1432.     delayPB.usbReqCount = 5;            // ~5ms (actually 5 frames at 1ms each)
  1433.     USBDelay(&delayPB);    
  1434. }
  1435.  
  1436. /************************************************************************************/
  1437. //
  1438. //    delayHandler
  1439. //
  1440. //    Completion handler for USB delay.
  1441. //
  1442. /************************************************************************************/
  1443.  
  1444. static void delayHandler(USBPB *pb)
  1445. {
  1446.  
  1447.     TraceMessage(0, kDrvName"- Entering delayHandler");
  1448.  
  1449.     if (pb->usbStatus != noErr)
  1450.         StatusMessage(gEnetGlobals.deviceRef, kDrvName"- delayHandler: Error", pb->usbStatus);
  1451.  
  1452.     pb->usbStatus = kAvailableStatus;
  1453. }
  1454.  
  1455. /************************************************************************************/
  1456. //
  1457. //    ClearDevice
  1458. //
  1459. //    Set up and send ClearFeature request (for stall).
  1460. //
  1461. /************************************************************************************/
  1462.  
  1463. void ClearDevice(void)
  1464. {
  1465.  
  1466.     TraceMessage(0, kDrvName"- Entering ClearDevice");
  1467.     
  1468.     if (TimeoutStallRequest())
  1469.         return;
  1470.         
  1471.     stallPB.usbStatus = noErr;
  1472.     stallPB.usbReference = gEnetGlobals.deviceRef;
  1473.     stallPB.usbRefcon = 1;
  1474.     stallHandler(&stallPB);
  1475. }
  1476.  
  1477. /************************************************************************************/
  1478. //
  1479. //    stallHandler
  1480. //
  1481. //    Completion handler for clear device/stall.
  1482. //
  1483. /************************************************************************************/
  1484.  
  1485. static void stallHandler(USBPB *pb)
  1486. {
  1487. OSStatus    err = 0;
  1488.  
  1489.     TraceMessage(0, kDrvName"- Entering StallHandler");
  1490.     
  1491.     if (pb->usbStatus != noErr)
  1492.     {
  1493.         USBExpertFatalError(gEnetGlobals.deviceRef, pb->usbStatus, kDrvName"- stallHandler: Error", pb->usbRefcon);
  1494.         return;
  1495.     }
  1496.     
  1497.     // May have to do more here (like find out which endpoint is stalled) which is why an FSM is used
  1498.     do{switch(pb->usbRefcon++)
  1499.     {
  1500.         case kEndpointStall:
  1501.             pb->usbStatus = noErr;
  1502.             pb->usbReference = gEnetGlobals.deviceRef;
  1503.             pb->pbVersion = kUSBCurrentPBVersion;    
  1504.             pb->usb.cntl.BMRequestType = USBMakeBMRequestType(kUSBOut, kUSBStandard, kUSBEndpoint);
  1505.     
  1506.             pb->usb.cntl.BRequest = kUSBRqClearFeature;
  1507.             pb->usb.cntl.WValue = 0;                        // Endpoint stall
  1508.             pb->usb.cntl.WIndex = 0;
  1509.             pb->usbReqCount = 0;
  1510.             pb->usbBuffer = nil;
  1511.  
  1512.             if(immediateError(err = USBDeviceRequest(pb)))
  1513.             {
  1514.                 StatusMessage(gEnetGlobals.deviceRef, kDrvName"- stallHandler: Device Req. error", err);
  1515.             }
  1516.         break;
  1517.         
  1518.         case kStallDone:
  1519.         // stall should now be cleared
  1520.             if (pb->usbStatus != noErr)
  1521.                 USBExpertFatalError(gEnetGlobals.deviceRef, pb->usbStatus, kDrvName"- stallHandler: stall completion error for bRequest", pb->usb.cntl.BRequest);
  1522.     
  1523.             pb->usbStatus = kAvailableStatus;
  1524.         break;
  1525.         
  1526.         default:
  1527.             StatusMessage(gEnetGlobals.deviceRef, kDrvName"- stallHandler: Internal Error unused case", (pb->usbRefcon-1));
  1528.         break;
  1529.     }
  1530.     break;    /* only execute once, unless continue used */
  1531.     }while(1);    /* so case can be reentered with a continue */
  1532. }
  1533.  
  1534. /************************************************************************************/
  1535. //
  1536. //    Asciify
  1537. //
  1538. //    Convert to Ascii character
  1539. //
  1540. /************************************************************************************/
  1541.  
  1542. UInt8 Asciify(UInt8 i)
  1543. {
  1544.  
  1545.     i &= 0xF;
  1546.     if ( i < 10 )
  1547.          return( '0' + i );
  1548.     else return( 55  + i );
  1549.     
  1550. }
  1551.  
  1552. #if ((DebugOn > 0) && (LogOn > 0))
  1553.  
  1554. #define dumplen        32        // Set this to the number of bytes to dump and the rest should work out correct
  1555.  
  1556. #define buflen        ((dumplen*2)+dumplen)+3
  1557. #define Asciistart    (dumplen*2)+3
  1558.  
  1559. /************************************************************************************/
  1560. //
  1561. //    USBLogData
  1562. //
  1563. //    Dumps the requested amount of data to the USB Expert log.
  1564. //
  1565. /************************************************************************************/
  1566.  
  1567. void USBLogData(UInt8 Dir, UInt32 Count, UInt8 *buf)
  1568. {
  1569.     UInt8        wlen, i, Aspnt, Hxpnt;
  1570.     UInt8        wchr;
  1571.     UInt8        LocBuf[buflen];
  1572.  
  1573.     for ( i=1; i<=buflen; i++)
  1574.     {
  1575.         LocBuf[i] = 0x20;
  1576.     }
  1577.     
  1578.     if (Dir == kUSBIn)
  1579.     {
  1580.         TraceMessage(1, kDrvName"- Read Complete");
  1581.     } else {
  1582.         if (Dir == kUSBOut)
  1583.         {
  1584.             TraceMessage(1, kDrvName"- Write");
  1585.         }
  1586.     }
  1587.  
  1588.     if (Count > dumplen)
  1589.     {
  1590.         wlen = dumplen;
  1591.     } else {
  1592.         wlen = Count;
  1593.     }
  1594.     
  1595.     if (wlen > 0)
  1596.     {
  1597.         Aspnt = Asciistart;
  1598.         Hxpnt = 1;
  1599.         for (i=1; i<=wlen; i++)
  1600.         {
  1601.             wchr = buf[i-1];
  1602.             LocBuf[Hxpnt++] = Asciify(wchr >> 4);
  1603.             LocBuf[Hxpnt++] = Asciify(wchr);
  1604.             if ((wchr < 0x20) || (wchr == 0x7F))         // Non printable characters
  1605.             {
  1606.                 LocBuf[Aspnt++] = 0x2E;                    // Replace with a period
  1607.             } else {
  1608.                 LocBuf[Aspnt++] = wchr;
  1609.             }
  1610.         }
  1611.         LocBuf[0] = (wlen + Asciistart) + 1;
  1612.         TraceMessage(1, LocBuf);
  1613.     } else {
  1614.         TraceMessage(1, kDrvName"- USBLogData: No data - Actual count=0");
  1615.     }
  1616. }
  1617. #endif
  1618.  
  1619. /***********************************************************************************/
  1620. //    Function:        InitDriver(CFragInitBlock *init)
  1621. //    Description:    This routine saves our connection id
  1622. //
  1623. //    Input:            init (unused)
  1624. //    Output:            noErr
  1625. /***********************************************************************************/
  1626.  
  1627. OSErr InitDriver(CFragInitBlock *init);
  1628. OSErr InitDriver(CFragInitBlock *init)
  1629. {
  1630.     OSErr    err = noErr;
  1631.     
  1632.     TraceMessage(0, kCRMName"- Entering initDriver");
  1633.     
  1634.     ConnID = init->connectionID;
  1635.  
  1636.     return err;
  1637. }